import configparser
import threading
import time
import schedule
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs
from modules.logger_config import setup_logger

# 使用统一的日志配置
logger = setup_logger('TaskScheduler')

# HTTP请求处理器类
class ActivationHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        parsed_url = urlparse(self.path)
        endpoint = self.server.scheduler.config['Server']['activation_endpoint']
        
        if parsed_url.path == endpoint:
            # 解析查询参数
            query_params = parse_qs(parsed_url.query)
            interface_type = query_params.get('type', [None])[0]
            
            # 验证接口类型参数
            if interface_type and interface_type not in ['peishu', 'daxiu']:
                self._send_response(400, {"status": "error", "message": "无效的接口类型，必须是peishu或daxiu"})
                return
            
            if interface_type:
                interface_name = "配属" if interface_type == 'peishu' else "大修"
                logger.info(f"接收到{interface_name}任务激活请求")
            else:
                logger.info("接收到双任务激活请求")
            
            # 执行对应任务
            self._run_activated_task(interface_type)
            
            if interface_type:
                interface_name = "配属" if interface_type == 'peishu' else "大修"
                self._send_response(200, {"status": "success", "message": f"{interface_name}任务已激活"})
            else:
                self._send_response(200, {"status": "success", "message": "双任务已激活"})
        else:
            self._send_response(404, {"status": "error", "message": "接口不存在"})

    def _run_activated_task(self, interface_type):
        """执行激活的任务"""
        self._run_task_thread(interface_type, auto_close=True)

    def _send_response(self, status, data):
        """发送HTTP响应"""
        import json
        self.send_response(status)
        self.send_header("Content-type", "application/json")
        self.end_headers()
        self.wfile.write(json.dumps(data).encode('utf-8'))

    # 绑定外部方法
    def _run_task_thread(self, interface_type, auto_close):
        self.server.scheduler._run_task_thread(interface_type, auto_close)

class TaskScheduler:
    def __init__(self, config_path, task_func):
        # 加载配置文件中的定时和服务器部分
        self.config = self._load_config(config_path)
        self.task_func = task_func  # 任务函数，支持interface_type参数
        self.running = True

    # 修改_load_config方法，确保编码参数正确设置
    def _load_config(self, config_path):
        """加载调度配置"""
        config = configparser.ConfigParser()
        config.read(config_path, encoding='utf-8')  # 确保有空格和正确的引号
        return config  # 返回完整配置对象

    def start_schedule(self):
        """启动定时任务"""
        cron_time = self.config['Cron']['time']
        # 定时任务执行双任务（配属和大修）
        schedule.every().day.at(cron_time).do(self._run_task_thread, interface_type=None, auto_close=True)
        logger.info(f"定时任务已启动，每天 {cron_time} 执行双任务（配属和大修）")

        # 启动调度线程，保存引用以便后续停止
        self._schedule_thread = threading.Thread(target=self._schedule_runner)
        # 不设为守护线程，确保能正确清理资源
        self._schedule_thread.start()

    def _schedule_runner(self):
        """调度器运行循环"""
        while self.running:
            schedule.run_pending()
            time.sleep(1)

    def _run_task_thread(self, interface_type=None, auto_close=True):
        """在新线程中执行任务（避免阻塞调度）"""
        if interface_type:
            interface_name = "配属" if interface_type == 'peishu' else "大修"
            logger.info(f"准备在新线程中执行{interface_name}任务")
        else:
            logger.info("准备在新线程中执行双任务")
            
        threading.Thread(target=self.task_func, 
                        args=(interface_type, auto_close), 
                        daemon=True).start()

    def start_activation_server(self):
        """启动激活服务器"""
        port = int(self.config['Server']['port'])
        endpoint = self.config['Server']['activation_endpoint']
        
        # 在独立线程中启动服务器
        self.activation_server_thread = threading.Thread(
            target=self._start_server_thread, 
            args=(port, endpoint),
            daemon=True  # 设置为守护线程，确保主进程退出时它也会终止
        )
        self.activation_server_thread.start()

    def _start_server_thread(self, port, endpoint):
        """在新线程中启动HTTP服务器"""
        # 创建服务器并绑定调度器引用
        server = HTTPServer(("", port), ActivationHandler)
        server.scheduler = self  # 将调度器实例绑定到服务器
        
        # 保存服务器引用以便后续停止
        self._http_server = server
        
        logger.info(f"激活服务器已启动，端口: {port}，激活地址: http://localhost:{port}{endpoint}")
        logger.info(f"- 调用双任务: http://localhost:{port}{endpoint}")
        logger.info(f"- 调用配属任务: http://localhost:{port}{endpoint}?type=peishu")
        logger.info(f"- 调用大修任务: http://localhost:{port}{endpoint}?type=daxiu")
        
        try:
            # 使用轮询方式运行服务器，而不是直接调用serve_forever
            # 这样可以更可靠地响应停止信号
            while self.running:
                # 处理一个请求（最多等待1秒）
                server.handle_request()
        except Exception as e:
            # 处理服务器停止时的异常
            if self.running is False:
                # 如果是正常停止，则不报错
                logger.info("HTTP服务器已停止")
            else:
                logger.error(f"服务器运行出错: {str(e)}")
        finally:
            try:
                server.server_close()
                logger.info("服务器资源已释放")
            except Exception as e:
                logger.error(f"关闭服务器资源时出错: {str(e)}")

    def stop(self):
        """停止服务，确保所有线程和服务器都能正确终止"""
        self.running = False
        
        # 停止激活服务器（如果存在）
        if hasattr(self, 'activation_server_thread') and self.activation_server_thread:
            logger.info("正在停止激活服务器...")
            try:
                # 通过设置running=False标志来通知服务器线程退出循环
                # 不需要调用shutdown()，避免潜在的阻塞问题
                
                # 向服务器发送一个虚拟请求以唤醒等待中的handle_request
                # 这样可以确保服务器线程能够及时检测到running=False标志
                import socket
                try:
                    if hasattr(self, '_http_server') and self._http_server:
                        # 发送一个简单的请求来唤醒服务器
                        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                        sock.settimeout(1)
                        sock.connect(("localhost", self._http_server.server_address[1]))
                        sock.send(b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n")
                        sock.close()
                except Exception as wake_error:
                    # 唤醒请求失败不影响停止流程
                    logger.debug(f"尝试唤醒服务器失败: {str(wake_error)}")
                
                # 等待激活服务器线程结束
                self.activation_server_thread.join(timeout=5)  # 最多等待5秒
                if self.activation_server_thread.is_alive():
                    logger.warning("激活服务器线程未能在超时时间内结束")
                else:
                    logger.info("激活服务器已成功停止")
            except Exception as e:
                logger.error(f"停止激活服务器时出错: {str(e)}")
        
        # 停止调度运行线程（如果存在）
        if hasattr(self, '_schedule_thread') and self._schedule_thread:
            logger.info("正在停止调度线程...")
            try:
                self._schedule_thread.join(timeout=3)  # 最多等待3秒
                if self._schedule_thread.is_alive():
                    logger.warning("调度线程未能在超时时间内结束")
                else:
                    logger.info("调度线程已成功停止")
            except Exception as e:
                logger.error(f"停止调度线程时出错: {str(e)}")
                
        logger.info("调度器已停止")